﻿/*
 * 穿梭框
 */
layui.define(['laytpl', 'form'], function (exports) {
    "use strict";

    var $ = layui.$
        , laytpl = layui.laytpl
        , layer = layui.layer
        , form = layui.form
        , hint = layui.hint()
        //外部接口
        , transfer = {
            config: {
                checkName: 'LAY_CHECKED' //是否选中状态的字段名
                , indexName: 'LAY_TABLE_INDEX' //下标索引名
            } //全局配置项
            , cache: {} //数据缓存
            , index: layui.transfer ? (layui.transfer.index + 10000) : 0

            //设置全局项
            , set: function (options) {
                var that = this;
                that.config = $.extend({}, that.config, options);
                return that;
            }

            //事件监听
            , on: function (events, callback) {
                return layui.onevent.call(this, MOD_NAME, events, callback);
            }
        }
        //操作当前实例
        , thisTransfer = function () {
            var that = this
                , options = that.config
                , id = options.id;

            id && (thisTransfer.config[id] = options);

            return {
                reload: function (options) {
                    that.reload.call(that, options);
                }
                , config: options
            }
        }
        //字符常量
        , MOD_NAME = 'transfer', ELEM = '.layui-table', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled', NONE = 'layui-none'
        , LEFT_PANEL = 'transfer-panel-left', RIGHT_PANEL = 'transfer-panel-right'
        , TPL_Form = ['<div class="transfer-panel {{ d.footer ? "transfer-panel-with-footer" : "" }} {{ d.class }}">'
            , '<div class="transfer-header">'
            , '{{# if(d.checkAll){ }}'
            , '<input lay-filter="transferCheckAll" type="checkbox" tip="全选" lay-skin="primary"> '
            , '{{# } }}'
            , '{{ d.title }}'
            , '{{# if(d.count){ }}'
            , '<span class="transfer-header-count">{{ d.items ? d.items.length : 0 }}</span>'
            , '{{# } }}'
            , '</div><div class="transfer-div {{ d.search ? "transfer-div-with-search" : "" }} {{ d.footer ? "transfer-div-with-footer" : "" }}">'
            , '{{# if(d.search){ }}'
            , '<dd data-value="" class="transfer-search-div">'
            , '<i class="layui-icon drop-search-btn"></i>'
            , '<input class="layui-input search_condition" placeholder="关键字搜索">'
            , '<i class="layui-icon clear-btn">&#x1006;</i>'
            , '</dd>'
            , '{{# } }}'
            , '<div class="transfer-content">'
            , '</div></div>'
            , '{{# if(d.footer){ }}'
            , '<div class="transfer-footer">'
            , '<div style="float:right;"><button title="刷新" lay-name="" class="layui-btn layui-btn-normal layui-btn-sm"><i class="layui-icon layui-icon-refresh"></i>刷新</button></div>'
            , '</div>'
            , '{{# } }}'
            , '</div>'
        ].join('')
        , TPL_Button = ['<div class="transfer-operation">'
            , '<button title="{{ d.toRight }}" lay-name="" class="layui-btn layui-btn-normal layui-btn-sm layui-btn-disabled"><i class="layui-icon layui-icon-next"></i></button>'
            , '<button title="{{ d.toLeft }}" lay-name="" class="layui-btn layui-btn-normal layui-btn-sm layui-btn-disabled"><i class="layui-icon layui-icon-prev"></i></button>'
            , '</div>'
        ].join('')
        , TPL_Item = ['<dd data-value="{{ d.value }}" data-title="{{ d.text }}">'
            , '<input type="checkbox" lay-filter="transferCheckItem" title="{{ d.text }}" lay-skin="primary">'
            , '</dd>'
        ].join('')

        , _WIN = $(window)
        , _DOC = $(document)

        //构造器
        , Class = function (options) {
            var that = this;
            that.index = ++transfer.index;
            that.config = $.extend({}, that.config, transfer.config, options);
            that.render();
        };

    //默认配置
    Class.prototype.config = {
        format: {
            valueName: "id",
            titleName: "name",
            selectName: "check"
        },
        checkAll: true,
        count: true,
        lTitle: "源列表",
        rTitle: "目标列表",
        toRight: "右移",
        toLeft: "左移",
        lSearch: true,
        rSearch: true,
        lFooter: false,
        rFooter: false
    };

    //穿梭框渲染
    Class.prototype.render = function () {
        var that = this
            , options = that.config;

        options.elem = $(options.elem);
        options.where = options.where || {};
        options.id = options.id || options.elem.attr('id');
        options.elem.attr("lay-filter", "LAY-transfer-" + that.index);

        //请求参数的自定义格式
        options.request = $.extend({
            pageName: 'page'
            , limitName: 'limit'
        }, options.request);

        //响应数据的自定义格式
        options.response = $.extend({
            statusName: 'code'
            , statusCode: 0
            , msgName: 'msg'
            , dataName: 'data'
        }, options.response);

        if (!options.elem[0]) return that;

        var leftElem = $(laytpl(TPL_Form).render({
            class: LEFT_PANEL
            , checkAll: options.checkAll
            , title: options.lTitle
            , count: options.count
            , search: options.lSearch
            , footer: options.lFooter
        }));
        var rightElem = $(laytpl(TPL_Form).render({
            class: RIGHT_PANEL
            , checkAll: options.checkAll
            , title: options.rTitle
            , count: options.count
            , search: options.rSearch
            , footer: options.rFooter
        }));
        var btns = $(laytpl(TPL_Button).render({
            toLeft: options.toLeft
            , toRight: options.toRight
        }));

        options.elem.append(leftElem).append(btns).append(rightElem);

        that.LeftForm = options.elem.find(".transfer-panel-left .transfer-content");
        that.RightForm = options.elem.find(".transfer-panel-right .transfer-content");
        that.LeftCount = options.elem.find(".transfer-panel-left .transfer-header-count");
        that.RightCount = options.elem.find(".transfer-panel-right .transfer-header-count");

        that.pullData();
        that.events();
    }

    //获得数据
    Class.prototype.pullData = function (loadIndex) {
        var that = this
            , options = that.config
            , request = options.request
            , response = options.response
            , sort = function () {
                if (typeof options.initSort === 'object') {
                    that.sort(options.initSort.field, options.initSort.type);
                }
            };

        that.startTime = new Date().getTime(); //渲染开始时间

        if (options.url) { //Ajax请求
            var params = {};

            //参数
            var data = $.extend(params, options.where);
            if (options.contentType && options.contentType.indexOf("application/json") == 0) { //提交 json 格式
                data = JSON.stringify(data);
            }

            $.ajax({
                type: options.method || 'get'
                , url: options.url
                , contentType: options.contentType
                , data: data
                , dataType: 'json'
                , headers: options.headers || {}
                , success: function (res) {
                    if (res[response.statusName] && res[response.statusName] != response.statusCode) {
                        that.renderForm();
                        that.LeftForm.html('<div class="' + NONE + '">' + (res[response.msgName] || '返回的数据状态异常') + '</div>');
                    } else {
                        that.renderData(res);
                        options.time = (new Date().getTime() - that.startTime) + ' ms'; //耗时（接口请求+视图渲染）
                    }
                    loadIndex && layer.close(loadIndex);
                    typeof options.done === 'function' && options.done(res);
                }
                , error: function (e, m) {
                    that.LeftForm.html('<div class="' + NONE + '">数据接口请求异常</div>');
                    that.renderForm();
                    loadIndex && layer.close(loadIndex);
                }
            });
        } else if (options.data && options.data.constructor === Array) { //已知数据
            var res = {}

            res[response.dataName] = options.data;//options.data.concat().splice(startLimit, options.limit);

            that.renderData(res);
            typeof options.done === 'function' && options.done(res);
        }
    };

    //数据渲染
    Class.prototype.renderData = function (data) {
        var that = this;
        layui.each(data, function (index, item) {
            var html = $(laytpl(TPL_Item).render(item));
            if (item.selected) that.RightForm.append(html);
            else that.LeftForm.append(html);
        });
        that.renderForm();
        that.refreshCount();
    }

    //渲染表单
    Class.prototype.renderForm = function (type) {
        form.render(type, 'LAY-transfer-' + this.index);
    }

    //渲染指定checkbox
    Class.prototype.renderCheckbox = function (inputs) {
        form.render("checkbox", inputs);
    }

    Class.prototype.refreshCount = function () {
        this.LeftCount && this.LeftCount.text(this.LeftForm.find("dd").length);
        this.RightCount && this.RightCount.text(this.RightForm.find("dd").length);
    }

    //事件处理
    Class.prototype.events = function () {
        var that = this;
        //全选
        form.on('checkbox(transferCheckAll)', function (data) {
            var $this = $(data.elem);
            var _parent = $this.parents(".transfer-panel");
            var inputs = _parent.find(".transfer-content").find("dd input[type='checkbox']");
            layui.each(inputs, function (index, input) {
                if ($this.is(':checked') && !$(input).is(':checked')) {
                    input.checked = true;
                }
                else if (!$this.is(':checked') && $(input).is(':checked')) {
                    input.checked = false;
                }
            });
            that.renderCheckbox(inputs);
            var btn = _parent.hasClass("transfer-panel-left") ? _parent.parent().find(".transfer-operation button:first") : _parent.parent().find(".transfer-operation button:last");
            if ($this.is(':checked'))
                $(btn).removeClass("layui-btn-disabled");
            else $(btn).not(".layui-btn-disabled").addClass("layui-btn-disabled");
        });
        //单选
        form.on('checkbox(transferCheckItem)', function (data) {
            var $this = $(data.elem);
            var _parent = $this.parents(".transfer-panel");
            var btn = _parent.hasClass("transfer-panel-left") ? _parent.parent().find(".transfer-operation button:first") : _parent.parent().find(".transfer-operation button:last");
            if (data.elem.checked) {
                $(btn).removeClass("layui-btn-disabled");
            }
            else {
                var inputs = _parent.find(".transfer-content").find("dd input[type='checkbox']:checked");
                if (inputs.length === 0) $(btn).not(".layui-btn-disabled").addClass("layui-btn-disabled");
                var checkAll = _parent.find(".transfer-header input[type='checkbox']:checked");
                if (checkAll.length > 0) {
                    checkAll[0].checked = false;
                    that.renderCheckbox(checkAll);
                }
            }
        });
        that.config.elem.on('click', '.transfer-operation button:not(.layui-btn-disabled)', function () {
            var from, to;
            if ($(this).attr("title") === that.config.toRight) {
                from = that.LeftForm;
                to = that.RightForm;
            }
            else {
                from = that.RightForm;
                to = that.LeftForm;
            }
            $(this).addClass("layui-btn-disabled");
            var inputs = from.find("dd input[type='checkbox']:checked");
            layui.each(inputs, function (index, input) {
                input.checked = false;
                $(input).parent().removeClass("layui-hide");
                to.append($(input).parent());
            });
            that.renderCheckbox(inputs);
            that.refreshCount();
            var checkAll = from.parents(".transfer-panel").find(".transfer-header input[type='checkbox']:checked");
            if (checkAll.length > 0) {
                checkAll[0].checked = false;
                that.renderCheckbox(checkAll);
            }
        });
        that.config.elem.on("keypress", " .transfer-search-div .search_condition", function (e) {
            e.stopPropagation();
            if (/^13$/.test(e.keyCode)) {//回车搜索
                searchData($(this));
            }
        });
        /**清空搜索条件**/
        that.config.elem.on("click", ".transfer-search-div .clear-btn", function (e) {
            $(this).prev().val("");
            searchData($(this));
        });
        /**获取搜索后的数据  **/
        function searchData($input) {
            var value = $input.val();
            var dds = $input.parents(".transfer-div").find(".transfer-content dd");
            if (value == "") {
                dds.filter(".layui-hide").removeClass("layui-hide");
            }
            else {
                //显示搜索结果菜单
                var patt = new RegExp(value);
                layui.each(dds, function (index, item) {
                    if (patt.test($(item).data("title"))) {
                        $(item).hasClass("layui-hide") && $(item).removeClass("layui-hide");
                    }
                    else {
                        !$(item).hasClass("layui-hide") && $(item).addClass("layui-hide");
                    }
                });
            }
        }
    }

    thisTransfer.config = {};

    transfer.getSelectedItems = function (id) {
        var dds = $(id).find(".transfer-panel-right .transfer-content dd");
        var keys = [];
        layui.each(dds, function (index, item) {
            keys.push($(item).data("value"))
        });
        return keys;
    }

    //核心入口
    transfer.render = function (options) {
        var inst = new Class(options);
        return thisTransfer.call(inst);
    };
    exports(MOD_NAME, transfer);

});

